package com.example.exception;

import com.example.model.api.Result;
import com.example.model.api.ResultBuilder;
import com.example.utils.I18nMessageTool;
import com.example.utils.JSON;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.resource.NoResourceFoundException;

import java.util.HashMap;
import java.util.List;

@RestControllerAdvice
@Slf4j
public class WebGlobalExceptionHandler {

  public String getMessage(Exception e) {
    String message = e.getMessage();
    if (message == null) {
      String message1 = e.getCause().getMessage();
      if (message1 != null) {
        message = message1;
      }
    }
    log.error("异常信息：{}", message);
    return message;
  }

  @ExceptionHandler(value = Exception.class)
  public Result<String> exceptionHandler(HttpServletResponse response, Exception e) {
    response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    return ResultBuilder.<String>aResult()
            .msg(getMessage(e))
            .code(HttpStatus.INTERNAL_SERVER_ERROR.value())
            .build();
  }

  @ExceptionHandler(value = NoResourceFoundException.class)
  public Result<String> exceptionHandler(HttpServletResponse response, NoResourceFoundException e) {
    response.setStatus(HttpStatus.NOT_FOUND.value());
    return ResultBuilder.<String>aResult()
        .msg(getMessage(e))
        .code(HttpStatus.NOT_FOUND.value())
        .build();
  }

  @ExceptionHandler(value = MethodArgumentNotValidException.class)
  public Result<String> exceptionHandler(HttpServletResponse response, MethodArgumentNotValidException e) {
    response.setStatus(HttpStatus.BAD_REQUEST.value());

    // 国际化翻译 数据校验异常信息
    BindingResult result = e.getBindingResult();
    List<FieldError> fieldErrors = result.getFieldErrors();
    HashMap<String, String> errorFields = new HashMap<>();
    for (FieldError error : fieldErrors) {
      String fieldName = error.getField();
      errorFields.put(fieldName, I18nMessageTool.translate(error.getDefaultMessage()));
    }

    return Result.fail(JSON.stringify(errorFields));
  }

  @ExceptionHandler(value = BaseException.class)
  public Result<String> exceptionHandler(HttpServletResponse response, BaseException e) {
    response.setStatus(e.getHttpStatus().value());
    return createResult(e);
  }

  private Result<String> createResult(BaseException e) {
    return ResultBuilder.<String>aResult()
        .msg(getMessage(e))
        .code(HttpStatus.INTERNAL_SERVER_ERROR.value())
        .build();
  }
}
